home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / c / mail110 / utils.c < prev    next >
C/C++ Source or Header  |  1994-02-23  |  12KB  |  571 lines

  1. //=========================================================
  2. //
  3. //    utils.c
  4. //
  5. //    This file contains a number of utilities that other
  6. //    routines use.
  7. //
  8. //=========================================================
  9.  
  10. // $Id: utils.c,v 1.5 1994/02/23 17:42:44 gbj Exp user $
  11.  
  12. /*
  13. $Log: utils.c,v $
  14.  * Revision 1.5  1994/02/23  17:42:44  gbj
  15.  * Removed check for user@host in replace_alias()
  16.  *
  17.  * Revision 1.4  1994/02/20  19:14:04  gbj
  18.  * Added mail aliasing.
  19.  *
  20.  * Revision 1.3  1994/02/20  19:12:24  gbj
  21.  * Added mail aliasing in setpost().
  22.  *
  23.  * Revision 1.2  1994/02/08  23:33:54  gbj
  24.  * First public release.
  25.  *
  26.  * Revision 1.1  1994/02/08  03:16:14  gbj
  27.  * Initial revision
  28.  *
  29. */
  30.  
  31. #include <time.h>
  32. #include "mailer.h"
  33. #include "utils.h"
  34.  
  35. static void replace_alias(char *to, char *real_to);
  36.  
  37. static char buf[4096], xbuf[4096], *bp;
  38.  
  39. //=========================================================
  40. // int get_sequence(void)
  41. //
  42. //    Open the sequence file ...\spool\mqueue\sequence.seq
  43. //    Read the sequence number, increment it, add 1 to it and
  44. //    rewrite the sequence file
  45. //    Close the sequence file and return the new sequence number.
  46. //
  47. //=========================================================
  48. int get_sequence(void)
  49. {
  50.     int res, seq;
  51.  
  52.     xfd=fopen(sequence, "rb+");    // Open for read and write
  53.     if (xfd == NULL)
  54.     {
  55.         perror("get_sequence");
  56.         fprintf(stderr, "Can't open %s\n", sequence);
  57.         return -1;
  58.     }
  59.     res=fscanf(xfd, "%d", &seq);
  60.     if (res != 1)
  61.     {
  62.         fprintf(stderr, "%s is corrupt\n", sequence);
  63.         fclose(xfd);
  64.         return -1;
  65.     }
  66.     seq++;
  67.     res=fseek(xfd, 0, SEEK_SET);
  68.     if (res == -1)
  69.     {
  70.         perror("get_sequence");
  71.         fprintf(stderr, "Can't set %s to beginning of file\n");
  72.         fclose(xfd);
  73.         return -1;
  74.     }
  75.     fprintf(xfd, "%d\n", seq);
  76.     fclose(xfd);
  77.     return seq;
  78. }
  79.  
  80. //=========================================================
  81. //    void set_paths(int seq)
  82. //
  83. //    Setup the relevant file names using the specified
  84. //    sequnce number.
  85. //
  86. //=========================================================
  87. void set_paths(int seq)
  88. {
  89.     char cmd[128];
  90.     
  91.     strcpy(wrk, mqueuepath);
  92.     strcat(wrk, "\\");            // ../mqueue/
  93.     sprintf(cmd, "%d", seq);    // nnn
  94.     strcat(wrk, cmd);            // ../mqueue/nnn
  95.     strcpy(txt, wrk);            // ../mqueue/nnn
  96.     strcat(wrk, ".wrk");        // ../mqueue/nnn.wrk
  97.     strcat(txt, ".txt");        // ../mqueue/nnn.txt
  98.     return;
  99. }
  100.  
  101. //=========================================================
  102. //    int set_wrk(char *to)
  103. //
  104. //    Setup the .wrk file contents, given the recipient.
  105. //
  106. //        recipient host [myhost if no host given]
  107. //        sender
  108. //        recipient
  109. //
  110. //=========================================================
  111. int set_wrk(char *to)
  112. {    
  113.     char xto[128];
  114.     char *u, *h;
  115.         
  116.     wfd=fopen(wrk, "wb");
  117.     if (wfd == NULL)
  118.     {
  119.         perror("set_wrk");
  120.         fprintf(stderr, "Can't open %s\n", wrk);
  121.         return 1;
  122.     }
  123.     
  124.     scaneol(to);
  125.     strcpy(xto, to);
  126.     u=strtok(xto, "@");
  127.     h=strtok(NULL, " ");
  128.     if (u == NULL)
  129.     {
  130.         fprintf(stderr, "Bad recipient %s\n", to);
  131.         fclose(wfd);
  132.         return 1;
  133.     }
  134.     if (*u == '\0')
  135.     {
  136.         fprintf(stderr, "Bad recipient %s\n", to);
  137.         fclose(wfd);
  138.         return 1;
  139.     }
  140.     // write host [note, if no host, write myhost]
  141.     if (h == NULL)
  142.         fprintf(wfd, "%s\n", host);
  143.     else if (*h == '\0')
  144.         fprintf(wfd, "%s\n", host);
  145.     else
  146.         fprintf(wfd, "%s\n", h);
  147.     // write sender
  148.     fprintf(wfd, "%s@%s\n", user, host);
  149.     // write recipient
  150.     fprintf(wfd, "%s\n", to);
  151.     fclose(wfd);
  152.     return 0;
  153. }
  154.  
  155. //=========================================================
  156. //    int set_txt(char *to, char *subject, int seq, char *xfile)
  157. //
  158. //    Setup the .txt file.
  159. //    The recipient, subject, sequence number and file to
  160. //    copy in are supplied.
  161. //
  162. //    The message headers are set up:
  163. //        Date:
  164. //        Message-Id:
  165. //        From:
  166. //        Reply-To:
  167. //        To:
  168. //        X-Mailer:
  169. //        Subject:
  170. //        <cr>
  171. //
  172. //    Then, if xfile != NULL, its contents are copied in.
  173. //    After this, any signature is coped in.
  174. //
  175. //=========================================================
  176. int set_txt(char *to, char *subject, int seq, char *xfile)
  177. {
  178.     char d[26];
  179.     char *ddd, *mmm, *dd, *hhmmss,*yyyy, *bp;
  180.     struct tm *ptr;
  181.     time_t t;
  182.  
  183.     time(&t);
  184.     ptr=gmtime(&t);
  185.     strcpy(d, asctime(ptr));
  186.     ddd=strtok(d, " \r\n");
  187.     mmm=strtok(NULL, " \r\n");
  188.     dd=strtok(NULL, " \r\n");
  189.     hhmmss=strtok(NULL, " \r\n");
  190.     yyyy=strtok(NULL, "\r\n");
  191.     
  192.     tfd=fopen(txt, "wb");
  193.     if (tfd == NULL)
  194.     {
  195.         perror("setpost");
  196.         fprintf(stderr, "setpost: Cannot open %s\n", txt);
  197.         return 1;
  198.     }
  199.     fprintf(tfd, "Date: %-3.3s, %-2.2s %-3.3s %-2.2s %-8.8s GMT\n",
  200.             ddd, dd, mmm, &(yyyy[2]), hhmmss);
  201.     fprintf(tfd, "Message-Id: <%d@%s>\n", seq, host);
  202.     fprintf(tfd, "From: %s@%s (%s)\n", user, host, name);
  203.     fprintf(tfd, "Reply-To: %s@%s\n", user, host);
  204.     fprintf(tfd, "To: %s\n", to);
  205.     fprintf(tfd, "X-Mailer: %s\n",VERSION);
  206.     fprintf(tfd, "Subject: %s\n\n", subject);
  207.     
  208.     // Copy any specified file
  209.     if (xfile != NULL)
  210.         if (*xfile != '\0')
  211.         {
  212.             xfd=fopen(xfile, "r");
  213.             if (xfd != NULL) {
  214.                 bp=fgets(buf, 4095, xfd);
  215.                 while (bp != NULL) {
  216.                     scaneol(buf);
  217.                     strcat(buf, "\n");
  218.                     fputs(buf, tfd);
  219.                     bp=fgets(buf, 4095, xfd);
  220.                 }
  221.                 fclose(xfd);
  222.             }
  223.         }
  224.     
  225.     fprintf(tfd, "\n");
  226.     fprintf(tfd, "-- \n");    // RFC says signature is two dashes+space
  227.     // Copy in any signature file
  228.     xfd=fopen(sig, "rb");
  229.     if (xfd != NULL) {
  230.         scaneol(buf);
  231.         strcat(buf, "\n");
  232.         bp=fgets(buf, 4095, xfd);
  233.         while (bp != NULL) {
  234.             fputs(buf, tfd);
  235.             bp=fgets(buf, 4095, xfd);
  236.         }
  237.         fclose(xfd);
  238.     }
  239.     fclose(tfd);
  240.     return 0;
  241. }
  242.  
  243. //=========================================================
  244. //    int call_editor(void)
  245. //
  246. //    Call the user's favourite editor.
  247. //
  248. //    NOTE: the editor and file to edit are specified in the
  249. //    global char* variabled 'edit' and 'txt'.  These should
  250. //    really be passed as parameters.
  251. //
  252. //=========================================================
  253. int call_editor(void)
  254. {
  255.     char cmd[128];
  256.     int res;
  257.     
  258.     sprintf(cmd, "%s %s", edit, txt);
  259.     res=system(cmd);
  260.     if (res == -1)
  261.     {
  262.         perror("call_editor");
  263.         fprintf(stderr, 
  264.             "Couldn't run editor, command line is:\n");
  265.         fprintf(stderr, "%s\n", cmd);
  266.         return 1;
  267.     }
  268.     else
  269.         return 0;
  270. }
  271.  
  272. //=========================================================
  273. //    int tmp_msg(int msg, char *xfile, int quote, int copy_msg)
  274. //
  275. //    This routine is doing too many things!
  276. //
  277. //    Anyway, you are supplied with:
  278. //
  279. //        msg            the number of the message to copy
  280. //        xfile        the name of the file to copy this into
  281. //        quote        TRUE=quote each copied line (prepend >)
  282. //        copy_msg    TRUE=copy the message, FALSE=don't copy
  283. //
  284. //=========================================================
  285. int tmp_msg(int msg, char *xfile, int quote, int copy_msg)
  286. {
  287.     FILE *mfd, *xfd;
  288.     char *bp;
  289.     char dbuf[80];
  290.     
  291.     if (msg < 0 || msg > maxmsgno)
  292.     {
  293.         fprintf(stderr, "tmp_msg: Message %d does not exist\n", msg);
  294.         return 1;
  295.     }
  296.     
  297.     if (xfile == NULL)
  298.     {
  299.         fprintf(stderr, "tmp_msg: No filename given\n");
  300.         return 1;
  301.     }
  302.     if (*xfile == '\0')
  303.     {
  304.         fprintf(stderr, "tmp_msg: No filename given\n");
  305.         return 1;
  306.     }
  307.     
  308.     mfd=fopen(mbox, "rb");
  309.     if (mfd == NULL)
  310.     {
  311.         perror("tmp_msg");
  312.         fprintf(stderr, "tmp_msg:  Can't open mailbox %s\n", mbox);
  313.         return 1;
  314.     }
  315.     
  316.     if (fseek(mfd, mailix[msg].fpos, SEEK_SET) == -1)
  317.     {
  318.         perror("tmp_msg");
  319.         fclose(mfd);
  320.         fprintf(stderr, 
  321.             "tmp_msg: Can't set file to start of message [%ld]",
  322.             mailix[msg].fpos);
  323.             return 1;
  324.     }
  325.     
  326.     xfd=fopen(xfile, "wb");
  327.     if (xfd == NULL)
  328.     {
  329.         perror("tmp_msg");
  330.         fclose(mfd);
  331.         fprintf(stderr, "tmp_msg: Can't open %s\n", xfile);
  332.         return 1;
  333.     }
  334.     
  335.     // Skip the From .... line
  336.     bp=fgets(buf, 4095, mfd);
  337.     bp=fgets(buf, 4095, mfd);
  338.     if (copy_msg)
  339.     {
  340.         while (bp != NULL)
  341.         {
  342.             scaneol(buf);
  343.             strcat(buf, "\n");
  344.  
  345.             strncpy(dbuf, buf, 78);
  346.             dbuf[79]='\0';
  347.  
  348.             if (quote)
  349.             {
  350.                 strcpy(xbuf, ">");
  351.                 strcat(xbuf, buf);
  352.             }
  353.             else
  354.                 strcpy(xbuf, buf);
  355.             if (strncmp(buf, "From ", 5) == 0 && strchr(buf, '@'))
  356.                 break;
  357.             else
  358.             {
  359.                     // Not a From ... line, so put it out
  360.                     fputs(xbuf, xfd);
  361.             }
  362.             bp=fgets(buf, 4095, mfd);
  363.         }
  364.     }
  365.     fclose(mfd);
  366.     fclose(xfd);
  367.     return 0;
  368. }
  369.  
  370. //=========================================================
  371. //    int fcopy(char *from, char *to, int header)
  372. //
  373. //    Copy from file 'from' to file 'to', retain message
  374. //    headers if header=TRUE.
  375. //    If 'to' exists, you are asked if you want to Overwrite
  376. //    it, Append to it, or Quit (abandon) the copy.
  377. //
  378. //=========================================================
  379. int fcopy(char *from, char *to, int header)
  380. {
  381.     FILE *ifd, *ofd;
  382.     int header_skipped, res, done, append, c;
  383.     
  384.     header_skipped=FALSE;
  385.     append=FALSE;
  386.     res=access(to, 0);
  387.     if (res == 0)
  388.     {
  389.         done=FALSE;
  390.         while (!done)
  391.         {
  392.             printf("\n%s Exists, (O)verwrite, (A)ppend or (Q)uit? ", to);
  393.             c=toupper(getche());
  394.             putchar('\r');
  395.             putchar('\n');
  396.             if (c == 'O')
  397.             {
  398.                 done=TRUE;
  399.                 append=FALSE;
  400.             }
  401.             else if (c == 'A')
  402.             {
  403.                 done=TRUE;
  404.                 append=TRUE;
  405.             }
  406.             else if (c == 'Q')
  407.                 return -1;
  408.             else
  409.                 done=FALSE;
  410.         }
  411.     }
  412.     
  413.     ifd=fopen(from, "rb");
  414.     if (ifd == NULL)
  415.     {
  416.         perror("fcopy");
  417.         fprintf(stderr, "fcopy: Can't open %s\n", from);
  418.         return 1;
  419.     }
  420.     
  421.     if (append)
  422.         ofd=fopen(to, "ab");
  423.     else
  424.         ofd=fopen(to, "wb");
  425.     if(ofd == NULL)
  426.     {
  427.         perror("fcopy");
  428.         fprintf(stderr, "fcopy: Can't open %s\n", to);
  429.         fclose(ifd);
  430.         return 1;
  431.     }
  432.     
  433.     bp=fgets(buf, 4095, ifd);
  434.     while(bp != NULL)
  435.     {
  436.         scaneol(buf);
  437.         strcat(buf, "\n");
  438.         if (header)
  439.             fputs(buf, ofd);
  440.         else
  441.             if (header_skipped)
  442.                 fputs(buf, ofd);
  443.             else
  444.                 if (*buf == '\n' || *buf == '\r' || *buf == '\0')
  445.                     header_skipped=TRUE;
  446.  
  447.         bp=fgets(buf, 4095, ifd);
  448.     }
  449.     
  450.     fclose(ifd);
  451.     fclose(ofd);
  452.     return 0;
  453. }
  454.  
  455. //=========================================================
  456. //    void scaneol(char *buf)
  457. //
  458. //    Scan buf for \r and \n and replace with \0.
  459. //
  460. //
  461. //=========================================================
  462. void scaneol(char *buf)
  463. {
  464.     char *bp;
  465.     
  466.     bp=strchr(buf, '\n');
  467.     if (bp)
  468.         *bp='\0';
  469.     bp=strchr(buf, '\r');
  470.     if (bp)
  471.         *bp='\0';
  472. }
  473.  
  474. //=========================================================
  475. //    int setpost(char *to, char *subject, char *xfile)
  476. //
  477. //    Bump the sequence number in sequence.seq and save that
  478. //    number for this item.
  479. //    Translate any potential alias.
  480. //    open nnn.wrk and setup the control data, then close it.
  481. //    open nnn.txt and setup the default mail data, if xfile is
  482. //    not null, include this file in nnn.txt as well, then close it.
  483. //    Finally, call the user's editor.
  484. //
  485. //    Return 1 if an error has occurred, otherwise return 0.
  486. //
  487. //=========================================================
  488.  
  489. int setpost(char *to, char *subject, char *xfile)
  490. {
  491.     int res, seq;
  492.     char real_to[128];    
  493.     
  494.     replace_alias(to, real_to);
  495.     
  496.     seq=get_sequence();
  497.     if (seq == -1)
  498.         return 1;
  499.  
  500.     // Setup paths to files        
  501.     set_paths(seq);        
  502.         
  503.     // Now set up the .wrk file
  504.     res=set_wrk(real_to);
  505.     if (res)
  506.         return 1;
  507.     
  508.     // Now setup the .txt file
  509.     res=set_txt(real_to, subject, seq, xfile);
  510.     if (res)
  511.         return 1;
  512.             
  513.     // All done with the .txt file and call the editor
  514.     res=call_editor();
  515.     if (res)
  516.         return 1;
  517.     
  518.     // Bye-bye
  519.     return 0;
  520.  
  521. }
  522.  
  523. //=========================================================
  524. //    void replace_alias(char *to, char *real_to)
  525. //
  526. //    Scan the alias file and replace 'to' with any alias
  527. //    in 'real_to'.
  528. //    If the 'alias' file is not specified, or 'to' is not found,
  529. //    just copy 'to' to 'real_to'.
  530. //
  531. //    alias file format is:
  532. //
  533. //    potential_alias    real_address
  534. //
  535. //=========================================================
  536. static void replace_alias(char *to, char *real_to)
  537. {
  538.     FILE *fd;
  539.     
  540.     char buf[81], *f1, *f2;
  541.     
  542.     strcpy(real_to, to);                // Copy 'to' first
  543.     
  544.     if (*alias == '\0')                    // No alias file
  545.         return;
  546.         
  547.     fd=fopen(alias, "r");
  548.     if (fd == NULL)                        // Can't open alias file
  549.         return;
  550.         
  551.     while (fgets(buf, 80, fd))            // Get a line
  552.     {
  553.         f1=NULL;
  554.         f2=NULL;
  555.         f1=strtok(buf, " \t\n");        // Get first token
  556.         if (f1)                            // potential_alias?
  557.         {
  558.             f2=strtok(NULL, " \t\n");    // real_address?
  559.             if (f2)
  560.             {
  561.                 if (strcmp(to, f1) == 0)
  562.                 {
  563.                     strcpy(real_to, f2);
  564.                     break;
  565.                 }
  566.             }
  567.         }
  568.     }
  569.     fclose(fd);
  570. }
  571.